package com.shenda.device;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.google.common.collect.Lists;
import com.shenda.device.message.ReqMsg;
import com.swak.rxtx.Channels;
import com.swak.rxtx.channel.Channel;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

/**
 * 设备管理器
 * 
 * @author lifeng
 */
@Getter
@Setter
@Accessors(chain = true)
public class Devices implements Options {

	/**
	 * 全局唯一处理器
	 */
	private static Devices _ME = null;

	public static Devices me() {
		return _ME;
	}

	/**
	 * 设备管理器
	 */
	private Map<String, Device> devices = new ConcurrentHashMap<>();

	public Devices() {
		_ME = this;
	}

	/**
	 * 返回设备
	 * 
	 * @return
	 */
	public List<Device> devices() {
		return Lists.newCopyOnWriteArrayList(devices.values());
	}

	/**
	 * 获得设备
	 * 
	 * @param channel
	 * @return
	 */
	public Device getChannel(Channel channel) {
		return devices.get(channel.comm());
	}

	/**
	 * 已添加设备
	 * 
	 * @param channel
	 * @return
	 */
	public Devices connected(Channel channel) {
		devices.computeIfAbsent(channel.comm(), (v) -> {
			return new Device().connected(channel);
		});
		return this;
	}

	/**
	 * 已关闭设备
	 * 
	 * @param channel
	 * @return
	 */
	public Devices closed(Channel channel) {

		// 设置已经关闭
		devices.computeIfPresent(channel.comm(), (k, v) -> {
			return v.closed(channel);
		});

		// 清除已经关闭
		devices.values().removeIf(device -> {
			return !device.getChannel().isActive();
		});

		return this;
	}

	/**
	 * 连接
	 */
	@Override
	public void connect() {
		Channels.me().start();
		Channels.me().connect();
	}

	/**
	 * 关闭
	 */
	@Override
	public void close() {
		Channels.me().close();
	}

	/**
	 * 开始上传
	 */
	@Override
	public void startUpload() {
		devices.forEach((comm, device) -> {
			device.startUpload();
		});
	}

	/**
	 * 设备配置
	 */
	@Override
	public void deviceConfig(String cjms, String cjpl, String odr) {
		devices.forEach((comm, device) -> {
			device.deviceConfig(cjms, cjpl, odr);
		});
	}

	/**
	 * 发送命令
	 */
	@Override
	public void sendCommand(ReqMsg command) {
		devices.forEach((comm, device) -> {
			device.sendCommand(command);
		});
	}
}
